﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Data.SqlClient;
using System.Text.RegularExpressions;

namespace Janksen.Mapping
{
    public class BuildParameter
    {
        /// <summary>
        ///  根据查询语句，和包含数据的实体对象，自动生成参数列表
        /// </summary>
        /// <typeparam name="T">实体类型，获取实体的参数的时候作用</typeparam>
        /// <param name="commandText">包含参数的查询语句</param>
        /// <param name="dataObj">包含数据的实体对象</param>
        /// <param name="extraParams">不包含在实体对象中的参数</param>
        /// <returns></returns>
        public static SqlParameter[] BuildSqlParameter<T>(string commandText, T dataObj, params SqlParameter[] extraParams)
        {
            if (string.IsNullOrEmpty(commandText))
                throw new ArgumentNullException("commandText", "无效的查询语句。");

            Regex rx = new Regex(@"(?<paramName>@[\w\d_]+)",
                RegexOptions.Multiline | RegexOptions.Compiled);
            MatchCollection matches = rx.Matches(commandText);

            List<string> paramNameList = new List<string>();

            List<SqlParameter> paramList = new List<SqlParameter>();

            //添加额外的参数，如果有重复指定的，后面指定的优先级高
            if (extraParams != null)
            {
                for (int i = extraParams.Length - 1; i >= 0; i--)
                {
                    if (!paramList.Contains(extraParams[i]))
                    {
                        paramList.Add(extraParams[i]);
                        paramNameList.Add(extraParams[i].ParameterName);
                    }
                }
            }


            if (dataObj != null)
            {
                SqlParameter[] fieldParams = EntityExtendHelper.GetInstance<T>().GetSqlParamsValue(dataObj);

                //添加参数实体的参数（查询语句中的参数名称和实体的名称相符合才起作用）
                foreach (Match match in matches)
                {
                    string paramName = match.Groups["paramName"].Value;
                    if (!paramNameList.Contains(paramName))
                    {
                        foreach (SqlParameter parameter in fieldParams)
                        {
                            if (parameter.ParameterName.ToLower() == paramName.ToLower())
                            {
                                paramList.Add(parameter);
                                paramNameList.Add(paramName);
                            }
                        }
                    }
                }
            }

            return paramList.ToArray();
        }
    }
}
